using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Deployment;
using Microsoft.SharePoint.Utilities;


using zevenseas.LifeCycleManagement.Utilities;


namespace zevenseas.LifeCycleManagement.TimerJobs
{
    public class SiteLifeCycleGatherTimerjob : SPJobDefinition
    {
        private ErrorHandling errorHandling;

        DateTime preset = DateTime.MinValue;
        bool checkOnContentDate = false;
        bool checkOnLastSecurityDate = false;
        bool checkOnUsageDate = false;
        LCMStatus status;
        bool deleteSite = false;
        bool lockSite = false;
        bool mailOwner = false;
        int deletionSpan = 0;
        int emailSpan = 0;
        int lockSpan = 0;
        string useCustomList = string.Empty;

        [Persisted]
        protected int SitesProcessed;

        public int PSitesProcessed { get; set; }
        
         public SiteLifeCycleGatherTimerjob()
        : base()
        {
            errorHandling = new ErrorHandling();
            errorHandling.productName = "SiteLifeCycleGatherTimerjob";
            errorHandling.exeName = "zevenseas.LifeCycleManagement.TimerJobs";
        }

         public SiteLifeCycleGatherTimerjob(string name, SPWebApplication webApplication, SPServer server, SPJobLockType lockType)
        : base(name, webApplication, server, lockType)
        {
        }   

       
        public override void Execute(Guid contentDbId)
        {
            List<LCMSite> collectionOfSites = new List<LCMSite>();

            SiteLifeCycleSettings settings = WebApplication.GetChild<SiteLifeCycleSettings>("SiteLifeCycleSettings");
            if (settings != null)
            {
                checkOnContentDate = settings.lastContentModifiedDate;
                checkOnLastSecurityDate = settings.lastSecurityModifiedDate;
                checkOnUsageDate = settings.lastUsageDate;
                                
                deleteSite = settings.deleteSite;
                lockSite = settings.lockSite;
                mailOwner = settings.mailOwner;

                status = settings.status;
                      
                int days = settings.unusedSpan;
                preset = System.DateTime.Now.AddDays(-days);

                deletionSpan = settings.deleteSpan;
                emailSpan = settings.emailSpan;
                lockSpan = settings.lockSpan;
            }           

            try
            {
                List<LCMSite> unusedSites = GetSites(this.WebApplication);
                PublishDataIntoLCMSite(unusedSites);
            }
            catch (Exception error)
            {
                errorHandling.LogMessage(error.Message.ToString(), error);
            }

            //Storing the lastRunTime to show on the Overview Sites page
            if (this.Title == "LCMGatherJob_Manual")
            {
                GatherTimerJobStatus status = WebApplication.GetChild<GatherTimerJobStatus>("GatherTimerJobStatus");
                if (status == null)
                {
                    SPPersistedObject parent = WebApplication;
                    status = new GatherTimerJobStatus("GatherTimerJobStatus", parent, Guid.NewGuid());
                    status.Update();
                }
                status.LastRunTime = this.LastRunTime;
                status.Update();

            }
        }

        private void PublishDataIntoLCMSite(List<LCMSite> unusedSitesCollection)
        {
            try
            {                
                SPWebApplication webApplication = SPAdministrationWebApplication.Local;
                using (SPWeb web = webApplication.Sites[0].AllWebs["LCM"])
                {
                    SPList UnusedSitesList = web.Lists["UnusedSites"];
                    foreach (LCMSite unusedSite in unusedSitesCollection)
                    {
                        SPQuery query = new SPQuery();
                        //query.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + unusedSite.Title.ToString() + "</Value></Eq></Where>";
                        query.Query = "<Where><And><Eq><FieldRef Name='WebApplication' /><Value Type='Text'>" + this.WebApplication.Name.ToString() + "</Value></Eq><Eq><FieldRef Name='Title' /><Value Type='Text'>" + unusedSite.Title.ToString() + "</Value></Eq></And></Where>"; 


                        if (UnusedSitesList.GetItems(query).Count == 0)
                        {
                            SPListItem item = UnusedSitesList.Items.Add();
                            item["WebApplication"] = unusedSite.WebApplication;
                            item["SiteCollection"] = unusedSite.SiteCollection;
                            item["Status"] = status.ToString();

                            string emailAddresses = string.Empty;
                            foreach (string emailAddress in unusedSite.SiteOwners)
                            {
                                if (!string.IsNullOrEmpty(emailAddress))
                                {
                                    emailAddresses += emailAddress + ";";
                                }
                            }
                            item["OwnerEmailAddress"] = emailAddresses;
                            item["Title"] = unusedSite.Title.ToString();
                            item["LastUsageDate"] = unusedSite.LastUsageDate;
                            item["Size"] = unusedSite.Usage.ToString();
                            item["Url"] = unusedSite.Url.ToString();
                            item.Update();
                        }
                    }
                }
            }
            catch (Exception error)
            {
                errorHandling.LogMessage(error.Message.ToString(), error);
            }
        }
        
        private List<LCMSite> GetSites(SPWebApplication webApplication)
        {
            List<LCMSite> unusedSites = new List<LCMSite>();

            if (webApplication.Sites.Count > 0)
            {
                foreach (SPSite site in webApplication.Sites)
                {
                    using (site)
                    {
                        if (site != null)
                        {

                            using (SPSiteAdministration siteAdministration = new SPSiteAdministration(site.ID))
                            {
                            #region webGathering
                            //if (site.AllWebs.Count > 0)
                            //{
                            //    foreach (SPWeb web in site.AllWebs)
                            //    {
                            //        List<DateTime> dates = new List<DateTime>();

                            //        if (checkOnContentDate)
                            //        { dates.Add(web.LastItemModifiedDate); }
                            //        if (checkOnLastSecurityDate)
                            //        { dates.Add(site.LastSecurityModifiedDate); }
                            //        if (checkOnUsageDate)
                            //        { dates.Add(Utilities.Utilities.GetLastUsageDate(web)); }

                            //        //Sorting the list puts the newest date at the bottom of the array
                            //        dates.Sort();

                            //        DateTime latestDate = dates[dates.Count - 1];
                            //        //if (latestDate <= preset)
                            //        //{
                            //        CustomSite unusedSite = new CustomSite();
                            //        unusedSite.LastUsageDate = latestDate;
                            //        unusedSite.WebApplication = webApplication.Name;
                            //        unusedSite.SiteCollection = site.RootWeb.Title;
                            //        unusedSite.Title = web.Title;
                            //        unusedSite.Url = web.Url;

                            //        List<string> siteOwners = new List<string>();
                            //        if (web.HasUniqueRoleAssignments || web.HasUniqueRoleDefinitions)
                            //        {
                            //            siteOwners = Utilities.Utilities.GetSiteOwners(web);
                            //        }
                            //        else
                            //        {
                            //            siteOwners = Utilities.Utilities.GetSiteOwners(site.RootWeb);
                            //        }

                            //        unusedSite.SiteOwners = siteOwners;

                            //        unusedSites.Add(unusedSite);

                            //        //}

                            //        web.Close();
                            //        web.Dispose();
                            //    }
                            //}
                            #endregion

                                List<DateTime> dates = new List<DateTime>();

                                if (checkOnContentDate)
                                { dates.Add(site.LastContentModifiedDate); }
                                if (checkOnLastSecurityDate)
                                { dates.Add(site.LastSecurityModifiedDate); }
                                if (checkOnUsageDate)
                                { dates.Add(Utilities.Utilities.GetLastUsageDate(site.RootWeb)); }

                                //Sorting the list puts the newest date at the bottom of the array
                                dates.Sort();

                                DateTime latestDate = dates[dates.Count - 1];
                                if (latestDate <= preset)
                                {
                                    LCMSite unusedSite = new LCMSite();
                                    unusedSite.WebApplication = webApplication.Name.ToString();
                                    unusedSite.Title = siteAdministration.Title.ToString();
                                    unusedSite.Url = siteAdministration.Url.ToString();
                                    unusedSite.LastUsageDate = latestDate;

                                    List<string> siteOwners = new List<string>();
                                    siteOwners = Utilities.Utilities.GetSiteOwners(site);
                                    unusedSite.SiteOwners = siteOwners;

                                    //If site is locked then this throws an exception
                                    try
                                    {

                                        unusedSite.Usage = Convert.ToString((long)(siteAdministration.DiskUsed / 0x400L / 0x400L));
                                    }
                                    catch (Exception) { }

                                    unusedSites.Add(unusedSite);

                                    this.SitesProcessed++;
                                    this.Update();
                                }
                            }
                        }                      
                    }                                     
                }
            }

            return unusedSites;

        }

        #region oldcrap

        //public override void Execute(Guid contentDbId)
        //{
        //    List<CustomSite> collectionOfSites = new List<CustomSite>();
        //    GetConfiguration();

        //    _eventLog = new EventLog("SharePoint LifeCycle Management");
        //    _eventLog.Source = "Monitoring Site LifeCycle";

        //    try
        //    {
        //        SPSecurity.RunWithElevatedPrivileges(delegate()
        //        {
        //            //GetConfiguration();
        //            foreach (SPWebApplication webApplication in SPWebService.ContentService.WebApplications)
        //            {
        //                //We don't want to gather the SSP so checking if the webapplication has the SSP key in it's propertybag will do the trick
        //                if (!webApplication.Properties.ContainsKey("Microsoft.Office.Server.SharedResourceProvider"))
        //                {
        //                    List<CustomSite> unusedSites = GetSites(this.WebApplication);
        //                    PublishDataIntoLCMSite(unusedSites);
        //                }
        //            }
        //        });
        //    }
        //    catch (Exception error)
        //    {
        //        Console.WriteLine(error.Message.ToString());
        //    }
        //}

        //private bool GetConfiguration()
        //{

        //    bool defaultConfiguration = true;

        //    SPSecurity.RunWithElevatedPrivileges(delegate()
        //    {

        //        try
        //        {

        //            foreach (SPWebApplication webApplication in SPWebService.AdministrationService.WebApplications)
        //            {
        //                foreach (SPSite site in webApplication.Sites)
        //                {
        //                    if (site.RootWeb.Properties.ContainsKey("LCM_Configured"))
        //                    {
        //                        defaultConfiguration = false;
        //                        useCustomList = Utilities.Utilities.GetWebProperty("customlisturl", site.RootWeb.Properties);

        //                        deleteSite = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bDeleteSite", site.RootWeb.Properties));
        //                        lockSite = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bLockSite", site.RootWeb.Properties));
        //                        mailOwner = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bMailOwner", site.RootWeb.Properties));

        //                        if (Utilities.Utilities.GetWebProperty("TimePeriodDelete", site.RootWeb.Properties) != string.Empty)
        //                        { deletionSpan = Convert.ToInt32(Utilities.Utilities.GetWebProperty("TimePeriodDelete", site.RootWeb.Properties)); }

        //                        if (Utilities.Utilities.GetWebProperty("TimePeriodLock", site.RootWeb.Properties) != string.Empty)
        //                        { lockSpan = Convert.ToInt32(Utilities.Utilities.GetWebProperty("TimePeriodLock", site.RootWeb.Properties)); }

        //                        if (Utilities.Utilities.GetWebProperty("TimePeriodMail", site.RootWeb.Properties) != string.Empty)
        //                        { emailSpan = Convert.ToInt32(Utilities.Utilities.GetWebProperty("TimePeriodMail", site.RootWeb.Properties)); }

        //                        if (Utilities.Utilities.GetWebProperty("TimePeriodUnused", site.RootWeb.Properties) != string.Empty)
        //                        {
        //                            int days = Convert.ToInt32(Utilities.Utilities.GetWebProperty("TimePeriodUnused", site.RootWeb.Properties));
        //                            preset = System.DateTime.Now.AddDays(-days);
        //                        }
        //                        if (Utilities.Utilities.GetWebProperty("bLastContentModifiedDate", site.RootWeb.Properties) != string.Empty)
        //                        { checkOnContentDate = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bLastContentModifiedDate", site.RootWeb.Properties)); }

        //                        if (Utilities.Utilities.GetWebProperty("bLastSecurityModifiedDate", site.RootWeb.Properties) != string.Empty)
        //                        { checkOnLastSecurityDate = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bLastSecurityModifiedDate", site.RootWeb.Properties)); }

        //                        if (Utilities.Utilities.GetWebProperty("bLastUsageDate", site.RootWeb.Properties) != string.Empty)
        //                        { checkOnUsageDate = Convert.ToBoolean(Utilities.Utilities.GetWebProperty("bLastUsageDate", site.RootWeb.Properties)); }


        //                        site.RootWeb.Close();
        //                        site.RootWeb.Dispose();
        //                    }

        //                    site.Close();
        //                    site.Dispose();
        //                }
        //            }
        //        }
        //        catch (Exception error)
        //        {
        //            Console.WriteLine(error.Message.ToString());
        //        }

        //    });
        //    return defaultConfiguration;

        //}

        #endregion

      
        
       
    }
}
